package com.ccteam.fluidmusic.fluidmusic.common.utils

import android.content.Context
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaMetadataCompat
import com.ccteam.fluidmusic.fluidmusic.R
import com.ccteam.fluidmusic.fluidmusic.media.extensions.flag
import com.ccteam.fluidmusic.fluidmusic.media.extensions.id
import com.ccteam.fluidmusic.fluidmusic.media.extensions.title
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton

/**
 *
 * @author Xiaoc
 * @since 2020/12/26
 *
 * Media媒体ID相关
 * 提供一些操作来对浏览的parentId、mediaId进行处理
 *
 * 单例类，由Hilt管理
 */
@Singleton
class MediaIDHelper @Inject constructor(
    @ApplicationContext private val context: Context
) {
    private val mediaIdBuilder = StringBuilder()

    companion object{
        const val EMPTY_ROOT = "__EMPTY_ROOT__"
        const val LOCAL_MEDIA_ROOT = "__FM_LOCAL_ROOT__"
        const val LOCAL_MEDIA_ALL = "__FM_LOCAL_ALL__"
        const val LOCAL_MEDIA_ARTIST = "__FM_LOCAL_ARTIST__"
        const val LOCAL_MEDIA_ALBUM = "__FM_LOCAL_ALBUM__"
        const val LOCAL_MEDIA_MUSIC = "__FM_LOCAL_MUSIC__"

        const val ONLINE_MEDIA_ALBUM = "__FM_ONLINE_ALBUM__"
        const val ONLINE_MEDIA_ARTIST = "__FM_ONLINE_ARTIST__"
        const val ONLINE_MEDIA_PLAYLIST_SHEET = "__FM_ONLINE_PLAYLIST_SHEET__"
        const val ONLINE_MEDIA_NEW_MUSIC= "__FM_ONLINE_NEW_MUSIC__"
        const val ONLINE_MEDIA_HOT_MUSIC= "__FM_ONLINE_HOT_MUSIC__"
        const val ONLINE_MEDIA_SEARCH= "__FM_ONLINE_SEARCH__"
        const val ONLINE_MEDIA_CACHE= "__FM_ONLINE_CACHE__"

        const val OPTION_LOCAL_MEDIA_RESCAN = "option-rescan"

        const val PARENT_ID_TAG = "parentId"
        const val PLAYLIST_ADD_NEXT_PLAY = "playlistNextPlay"
        const val SORT_ORDER_TAG = "sort_order"
        const val IS_OFFLINE_TAG = "isOffline"
        const val CACHE_PLAY = "cachePlay"
        const val CACHE_PLAY_METADATA = "cachePlay_metadata"

        const val PLAYLIST_ADD_TYPE = "playlistAddType"
        const val PLAYLIST_ADD_TYPE_NEXT_PLAY = 1
        const val PLAYLIST_ADD_TYPE_NOW_PLAY = 2
        const val PLAYLIST_ADD_TYPE_LAST_PLAY = 3

        const val ALBUM_ART_URI = "content://media/external/audio/albumart"

        private const val LOCAL_TAG = "__FM_LOCAL_"

        /**
         * 多个标志之间的分隔符
         * __FM_LOCAL_ROOT__/1/__FM_LOCAL_ALBUM__/3
         */
        private const val CATEGORY_SEPARATOR = '/'


        fun isOnlineParentId(parentId: String?): Boolean{
            return parentId == ONLINE_MEDIA_ALBUM ||
                    parentId == ONLINE_MEDIA_ARTIST ||
                    parentId == ONLINE_MEDIA_PLAYLIST_SHEET ||
                    parentId == ONLINE_MEDIA_NEW_MUSIC ||
                    parentId == ONLINE_MEDIA_HOT_MUSIC ||
                    parentId == ONLINE_MEDIA_SEARCH ||
                    parentId == ONLINE_MEDIA_CACHE
        }
    }



    /**
     * 生成本地跟路径的内容
     */
    fun generateLocalRootChildren(): MutableList<MediaMetadataCompat> {
        val localAllMetadata = MediaMetadataCompat.Builder().apply {
            id = LOCAL_MEDIA_ALL
            title = context.resources.getString(R.string.local_music_all_title)
            flag = MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
        }.build()
        val localAlbumMetadata = MediaMetadataCompat.Builder().apply {
            id = LOCAL_MEDIA_ALBUM
            title = context.resources.getString(R.string.local_music_album_title)
            flag = MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
        }.build()
        val localArtistMetadata = MediaMetadataCompat.Builder().apply {
            id = LOCAL_MEDIA_ARTIST
            title = context.resources.getString(R.string.local_music_artist_title)
            flag = MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
        }.build()
        return mutableListOf(
                localAllMetadata,localAlbumMetadata,localArtistMetadata
        )
    }

    /**
     * 生成本地歌手详情页的Tab标签内容
     */
    fun generateLocalArtistChildren(artistId: String): MutableList<MediaMetadataCompat>{
        val artistMusicMetadata = MediaMetadataCompat.Builder().apply {
            id = createMediaId(LOCAL_MEDIA_ARTIST,artistId,LOCAL_MEDIA_MUSIC)
            title = context.resources.getString(R.string.local_music_all_title)
            flag = MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
        }.build()
        val artistAlbumMetadata = MediaMetadataCompat.Builder().apply {
            id = createMediaId(LOCAL_MEDIA_ARTIST,artistId, LOCAL_MEDIA_ALBUM)
            title = context.resources.getString(R.string.local_music_album_title)
            flag = MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
        }.build()
        return mutableListOf(
            artistMusicMetadata,artistAlbumMetadata
        )
    }

    /**
     * 创建MediaId
     * @param categories 不定参数
     *
     * 接收传来的不定参数，将其拼接为 XXX/XXX/XXX/XXX 样式
     */
    fun createMediaId(vararg categories: String?): String{
        mediaIdBuilder.setLength(0)

        val sb = mediaIdBuilder
        categories.forEach {
            sb.append(it)
            sb.append(CATEGORY_SEPARATOR)
        }
        sb.deleteCharAt(sb.length - 1)
        return sb.toString()
    }

    /**
     * 从MediaId中提取真正的音乐本身Id
     * 或者它是浏览的区域
     *
     * @param mediaId MediaId
     */
    fun extractMusicOrBrowseIdFromMediaId(mediaId: String): String{
        val pos = mediaId.indexOfLast {
            it == CATEGORY_SEPARATOR
        }
        return if(pos > 0) mediaId.substring(pos + 1) else mediaId
    }

    /**
     * 提取 root/xxx/xx 除去第一个 root 的mediaId
     * 例如 root/1/2 调用后为 1/2
     *
     * @param mediaId MediaId
     */
    fun extractBehindFirstMediaId(mediaId: String): String{
        val pos = mediaId.indexOfFirst {
            it == CATEGORY_SEPARATOR
        }
        return if(pos > 0) mediaId.substring(pos + 1) else mediaId
    }

    /**
     * 从MediaId中提取当前MediaId所在的浏览区域
     * @param mediaId MediaId
     */
    @Deprecated("请替换为 extractMusicOrBrowseIdFromMediaId")
    fun extractBrowseMediaId(mediaId: String): String{
        val pos = mediaId.indexOfLast {
            it == CATEGORY_SEPARATOR
        }
        return if(pos > 0) mediaId.substring(0,pos) else mediaId
    }

    /**
     * 从MediaId中提取当前MediaId所在的根节点区域
     * @param mediaId MediaId
     */
    fun extractBrowseRootId(mediaId: String): String{
        val pos = mediaId.indexOfFirst {
            it == CATEGORY_SEPARATOR
        }
        return if(pos > 0) mediaId.substring(0,pos) else mediaId
    }

    /**
     * 判断当前parentId是本地还是在线类型
     * @return 返回 true 代表是本地类型 false 为在线类型
     */
    fun checkLocalOrOnlineId(parentId: String): Boolean{
        return parentId.contains(LOCAL_TAG)
    }
}